package cn.shiro.shiroservice.auth.provider.absrtact;

import cn.shiro.shiroservice.auth.pojo.vo.out.UserInfoOutVo;
import cn.shiro.shiroservice.auth.provider.interfaces.AuthPermissionFilter;
import cn.shiro.shiroservice.auth.provider.interfaces.AuthenticationInfoFilter;
import cn.shiro.shiroservice.auth.provider.interfaces.impl.IAuthenticationTokenImpl;
import cn.shiro.shiroservice.auth.service.AccessCacheManager;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.permission.PermissionResolver;
import org.apache.shiro.authz.permission.RolePermissionResolver;
import org.apache.shiro.cache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * &#064;Time 2024 一月 星期三 09:16
 *
 * @author ShangGuan
 */
public abstract class AbstractUserInfoAware extends AbstractAuthResolverAware {

    private AuthenticationInfoFilter authenticationInfoFilter;


    private AccessCacheManager<? extends UserInfoOutVo> accessCacheManager;

    /**
     * 启用redis自定义缓存
     */
    private boolean enableRedisCache;

    private static Logger log = LoggerFactory.getLogger(AbstractUserInfoAware.class);

    protected AbstractUserInfoAware(
            PermissionResolver permissionResolver, RolePermissionResolver rolePermissionResolver,
            AuthPermissionFilter authPermissionFilter, AuthenticationInfoFilter authenticationInfoFilter,
            AccessCacheManager<? extends UserInfoOutVo> accessCacheManager
    ) {
        super(permissionResolver, rolePermissionResolver, authPermissionFilter);
        this.authenticationInfoFilter = authenticationInfoFilter;
        if (accessCacheManager != null) {
            this.accessCacheManager = accessCacheManager;
        }
    }

    protected AbstractUserInfoAware(PermissionResolver permissionResolver, RolePermissionResolver rolePermissionResolver,
                                    AuthPermissionFilter authPermissionFilter, AuthenticationInfoFilter authenticationInfoFilter) {
        this(permissionResolver, rolePermissionResolver, authPermissionFilter, authenticationInfoFilter, null);
    }



    public void setAuthenticationInfoFilter(AuthenticationInfoFilter authenticationInfoFilter) {
        this.authenticationInfoFilter = authenticationInfoFilter;
    }

    public void setAccessCacheManager(AccessCacheManager<? extends UserInfoOutVo> accessCacheManager) {
        this.accessCacheManager = accessCacheManager;
    }

    public AccessCacheManager<? extends UserInfoOutVo> getAccessCacheManager() {
        return accessCacheManager;
    }

    @Override
    public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException, ClassCastException {
        //调用初始化方法
        authenticationInfoFilter.init(getName());
        assertAuthenticationToken(authenticationToken);
        AuthenticationInfo authenticationInfo = doGetAuthenticationInfo(authenticationToken);
        authenticationInfoFilter.doCredentialsMatch(authenticationToken, authenticationInfo);
        //调用销毁方法
        authenticationInfoFilter.destroyed();
        return authenticationInfo;
    }

    /**
     * 每次缓存保存之前
     *
     * @param key   钥匙
     * @param param 参数
     */

    protected  void perCacheSave(String key,Object param){
        if(param instanceof UserInfoOutVo){
            save(key,param);
        }
        log.warn("{}:不是理想的类型",param.getClass());
        throw new CacheException(param.getClass()+"不是理想的类型");
    }
    protected abstract void save(String key,Object param);


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        return authenticationInfoFilter.doGetAuthenticationInfo(token);
    }

    /**
     * 身份验证令牌检查
     *
     * @param authenticationToken 认证令牌
     */

    protected void assertAuthenticationToken(AuthenticationToken authenticationToken) {
        if (!(authenticationToken instanceof IAuthenticationTokenImpl)) {
            log.info("不是理想的类,应该继承 类 IAuthenticationTokenImpl");
            throw new ClassCastException("不是理想的类");
        }
    }


}
